﻿using Levfier.Proccessors.Parameters;
using System;
namespace Levfier.Proccessors.Gain
{
    /// <summary>
    /// 非線形ゲイン
    /// </summary>
    [Serializable]
    public class AsymmetricalLinearGain : Proccessor
    {
        /// <summary>
        /// プラス領域のゲインに関するパラメータ
        /// </summary>
        private ProccessParameter plusGainParam;

        /// <summary>
        /// マイナス領域のゲインに関するパラメータ
        /// </summary>
        private ProccessParameter minusGainParam;

        /// <summary>
        /// プラス領域のゲインの正負に関するパラメータ
        /// </summary>
        private ProccessParameter plusInvertParam;

        /// <summary>
        /// マイナス領域のゲインの正負に関するパラメータ
        /// </summary>
        private ProccessParameter minusInvertParam;

        /// <summary>
        /// 入力を線形増幅する
        /// </summary>
        /// <param name="input">入力</param>
        /// <param name="output">出力</param>
        protected override void InnerProccess(double[] inputBuffer, double[] outputBuffer)
        {
            //パラメータを取り出す
            double plusGain = ProccessParameter.ConvertDBToValue(this.plusGainParam.Value);
            if (0 < this.plusInvertParam.Value)
            {
                plusGain = -plusGain;
            }

            //パラメータを取り出す
            double minusGain = ProccessParameter.ConvertDBToValue(this.minusGainParam.Value);
            if (0 < this.minusInvertParam.Value)
            {
                minusGain = -minusGain;
            }

            double temp;

            //計算
            for(int i = 0 ; i < inputBuffer.Length ; i++)
            {
                temp = inputBuffer[i];
                if (temp > 0.0d)
                {
                    outputBuffer[i] = plusGain * temp;
                }
                else
                {
                    outputBuffer[i] = minusGain * temp;
                }
                
            }
        }

        /// <summary>
        /// パラメータを初期化する
        /// </summary>
        protected override void InitParameters()
        {
            this.plusGainParam = new ProccessParameter();
            this.plusGainParam.Name = "Gain1[dB]";
            this.plusGainParam.Value = 0.0d;
            this.plusGainParam.MaxValue = 100.0d;
            this.plusGainParam.MinValue = -100.0d;
            this.plusGainParam.Step = 1.0d;
            this.parameters.Add(this.plusGainParam.Name, this.plusGainParam);

            this.plusInvertParam = new ProccessParameter();
            this.plusInvertParam.Type = ParameterType.Bool;
            this.plusInvertParam.Name = "Invert1";
            this.plusInvertParam.Value = 0.0d;
            this.plusInvertParam.MaxValue = 1.0d;
            this.plusInvertParam.MinValue = 0.0d;
            this.plusInvertParam.Step = 1.0d;
            this.parameters.Add(this.plusInvertParam.Name, this.plusInvertParam);

            this.minusGainParam = new ProccessParameter();
            this.minusGainParam.Name = "Gain2[dB]";
            this.minusGainParam.Value = 0.0d;
            this.minusGainParam.MaxValue = 100.0d;
            this.minusGainParam.MinValue = -100.0d;
            this.minusGainParam.Step = 1.0d;
            this.parameters.Add(this.minusGainParam.Name, this.minusGainParam);

            this.minusInvertParam = new ProccessParameter();
            this.minusInvertParam.Type = ParameterType.Bool;
            this.minusInvertParam.Name = "Invert2";
            this.minusInvertParam.Value = 0.0d;
            this.minusInvertParam.MaxValue = 1.0d;
            this.minusInvertParam.MinValue = 0.0d;
            this.minusInvertParam.Step = 1.0d;
            this.parameters.Add(this.minusInvertParam.Name, this.minusInvertParam);
        }
    }
}
